package grobit.torrent

class TorrentBuilder extends BuilderSupport {
    private final static String OBJ_NAME = 'OBJ_NAME'

    @Override
    protected void setParent(Object o, Object o1) {
        o.put(o1.get(OBJ_NAME), o1)
        def name = o1.remove(OBJ_NAME)
        println "set parent: ($name) " + o + ' ' + o1
    }

    @Override
    protected Object createNode(Object o) {
        println ('create node: ' + o)

        switch(o) {
            case 'torrent':
            case 'info':
                return [:]
            default:
                throw new Exception('Unsupported object: ' + o)
        }
    }

    @Override
    protected Object createNode(Object o, Object o1) {
        def node = createNode(o)
        println ('with-1: ' + o1)
    }

    @Override
    protected Object createNode(Object o, Map map) {
        println ('with-2 ' + o + ' ' + map)
        switch(o) {
            case 'torrent':
                Map node = createNode(o) as Map
                map.each { key, value ->
                    switch(key) {
                        case 'announce':
                        case 'comment':
                        case 'created by':
                        case 'encoding':
                            node.put(key, value as String)
                            break
                        case 'announce-list':
                            List al = node.get(key, [])
                            al.addAll(value)
                            break
                        case 'creation date':
                            node.put(key, new BigInteger(value.getTime()).divide(1000))
                            break
                        default:
                            throw new Exception('Unsupported: ' + key)
                    }
                }
                return node
            case 'info':
                Map node = createNode(o) as Map
                node.put(OBJ_NAME, o)
                map.each { key, value ->
                    switch(key) {
                        case 'piece length':
                        case 'length':
                            node.put(key, value as BigInteger)
                            break
                        case 'pieces':
                        case 'name':
                        case 'md5sum':
                            node.put(key, value as String)
                            break
                        case 'private':
                            node.put(key, (value ? 1 : 0) as BigInteger)
                            break
                        default:
                            throw new Exception('Unsupported: ' + key)
                    }
                }
                return node
            default:
                throw new Exception('Unsupported: ' + o)
        }
    }

    @Override
    protected Object createNode(Object o, Map map, Object o1) {
        def node = createNode(o)
        println ('with-3: ' + map + ' ' + o1)
    }
}
